package com.zhang.aspect;

import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.zhang.anno.SystemLog;
import com.zhang.entity.OperationLog;
import com.zhang.mapper.OperationLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;

/**
 * User: 张
 * Date: 2024-11-07
 * Time: 9:09
 * Description:
 */

@Slf4j
@Component
@Aspect
public class LogAspect {
    @Autowired
    private OperationLogMapper operationLogMapper;

    @Pointcut("@annotation(com.zhang.anno.SystemLog)")
    public void pt(){
    }


    @Around("pt()")
    public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable {

        Object ret;
        try {
            OperationLog operationLog = handleBefore(joinPoint);
            ret = joinPoint.proceed();
            handleAfter(ret,operationLog);
        } finally {
            log.info("=========End========={}", System.lineSeparator());
        }

        return ret;
    }

    private OperationLog handleBefore(ProceedingJoinPoint joinPoint) throws Exception {
        OperationLog operationLog = new OperationLog();

        // 获取 request
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();

//        String token = request.getHeader("token");
//        if (token != null){
//            operationLog.setUserId(Integer.parseInt(JwtUtil.parseJWT(token).get("sub").toString()));
//        }
        operationLog.setUserId(StpUtil.getLoginIdAsInt());


        // 获取被增强方法上的注解对象
        SystemLog systemLog = getSystemLog(joinPoint);

        log.info("=========Start========={}", System.lineSeparator());
        // 打印请求 URL
        log.info("URL   : {}",request.getRequestURL().toString());
        // 打印业务信息
        log.info("BusinessName : {}",systemLog.businessName());
        // 打印请求方法
        log.info("HTTP Method  : {}",request.getMethod());
        // 打印调用 controller 的全路径（类名）
        log.info("Class Method Path: {}",joinPoint.getSignature().getDeclaringTypeName());
        // 打印调用 controller 的执行方法
        log.info("Class Method : {}",((MethodSignature)joinPoint.getSignature()).getName());
        // 打印请求的 IP
        log.info("IP           : {}",request.getRemoteHost());
        // 打印请求入参
        log.info("Request Args : {}", joinPoint.getArgs());

        //业务信息
        operationLog.setBusinessName(systemLog.businessName());
        //请求方法
        operationLog.setHttpMethod(request.getMethod());
        //调用 controller 的全路径（类名）
        operationLog.setMethodPath(joinPoint.getSignature().getDeclaringTypeName());
        //调用 controller 的执行方法
        operationLog.setMethod(((MethodSignature)joinPoint.getSignature()).getName());

        Date date = new Date();

        //请求入参
//        if (JSON.toJSONString(joinPoint.getArgs()).length() >200){
//            operationLog.setArgs(JSON.toJSONString(joinPoint.getArgs()).substring(0,200));
//        }else {
//            operationLog.setArgs(JSON.toJSONString(joinPoint.getArgs()));
//        }
        String string = Arrays.toString(joinPoint.getArgs());
        if (string.length() >200){
            operationLog.setArgs(Arrays.toString(joinPoint.getArgs()).substring(0,200));
        }else {
            operationLog.setArgs(Arrays.toString(joinPoint.getArgs()));
        }
        //请求IP
        operationLog.setIp(request.getRemoteHost());

        return operationLog;
    }

    private void handleAfter(Object ret,OperationLog operationLog){
        // 请求出参
        if (JSON.toJSONString(ret).length() >200){
            operationLog.setResponse(JSON.toJSONString(ret).substring(0,200));
        }else {
            operationLog.setResponse(JSON.toJSONString(ret));
        }
        // 保存日志
        operationLogMapper.insertLog(operationLog);
        log.info("Response : {}",JSON.toJSON(ret));
    }

    private SystemLog getSystemLog(ProceedingJoinPoint joinPoint){
        // 获取被增强方法上的注解对象
        MethodSignature  methodSignature = (MethodSignature) joinPoint.getSignature();
        SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class);
        return systemLog;
    }




}